use axum::{extract::{Path, Query}, http::HeaderMap, Json};
use com::{ auth::claims::get_id, code, query, sea_orm::{ connect, crud, delete, cust::cust_blob, send_paging, send_sql_ok} };
use sea_orm::{ entity::*, query::* };
use model::template::{ ActiveModel, Column, Entity};

pub async fn list(Query(param): Query<JsonValue>) -> Result<Json<JsonValue>, Json<JsonValue>>{
    let sorter = crud::order::sort(&param, Entity,Column::Level, false)?;
    let selector = Entity::find()
    .select_only()
    .columns([ Column::Id, Column::Name, Column::NameEn, Column::Level, Column::Type ])
    .column_as(cust_blob("content"), "content")
    .column_as(cust_blob("content_union"), "content_union")
    .apply_if(query::str_op(&param,"name")?,  | q, v| q.filter(Column::Name.contains(v)) )
    .apply_if(query::str_op(&param,"type")?,  | q, v| q.filter(Column::Type.eq(v)) )
    .order_by_desc(Column::UpdateTime)
    .order_by(sorter.col, sorter.order);
    send_paging(selector, param).await
}
pub async fn save( header: HeaderMap, Json(body):Json<JsonValue> ) -> Result<Json<JsonValue>, Json<JsonValue>>{
    let conn = connect().await?;
    let user = get_id(header)?;
    let mut model = ActiveModel{
        name            : Set( query::str(&body, "name")? ),
        name_en         : Set( query::str(&body, "name_en")? ),
        content         : Set( query::blob(&body, "content")? ),
        content_union   : Set( query::blob_op(&body, "content_union")? ),
        r#type          : Set( query::str(&body, "type")? ),
        level           : Set( query::i16(&body, "level")? ),
        create_user     : Set( user.to_owned() ),
        ..Default::default()
    };
    if let Some(f) = query::i32_op(&body, "id")? {
        model.id = Set(f);
        model.update_user = Set( Some(user) );
        model.create_user = NotSet;
    }
    let result = model.save(&conn).await;
    send_sql_ok(&conn, result).await
}
pub async fn find(Path( id ): Path<i32>) -> Result<Json<JsonValue>, Json<JsonValue>>{
    let conn = connect().await?;
    let result = Entity::find_by_id(id)
    .select_only()
    .columns([ 
        Column::Id, Column::Name, Column::NameEn, Column::Level, Column::Type
    ])
    .column_as(cust_blob("content"), "content")
    .column_as(cust_blob("content_union"), "content_union")
    .into_model()
    .one(&conn).await;

    code::send_op_obj( result )
}
pub async fn del(Path( id ): Path<String>) -> Result<Json<JsonValue>, Json<JsonValue>>{ delete::del::by_ids(Entity, &id, None).await }

pub async fn dict() -> Result<Json<JsonValue>, Json<JsonValue>>{
    let conn = connect().await?;
    let result = Entity::find()
    .select_only()
    .column_as(Column::Name, "label")
    .column_as(cust_blob("content"), "value")
    .column_as(cust_blob("content_union"), "union")
    .filter(Column::Type.eq("sea_orm_file"))
    .into_json().all(&conn).await;
    code::send_arr(result)
}
pub async fn dict_front() -> Result<Json<JsonValue>, Json<JsonValue>>{
    let conn = connect().await?;
    let result = Entity::find()
    .select_only()
    .column_as(Column::Name, "label")
    .column_as(cust_blob("content"), "value")
    .filter(Column::Type.eq("react_file"))
    .into_json().all(&conn).await;
    code::send_arr(result)
}
pub async fn table() -> Result<Json<JsonValue>, Json<JsonValue>>{
    let conn = connect().await?;
    let result = Entity::find()
    .select_only()
    .columns([ Column::Name ])
    .column_as(cust_blob("content"), "content")
    .filter(Column::NameEn.eq("table"))
    .into_json().one(&conn).await;
    code::send_op_obj(result)
}
pub async fn dict_migration() -> Result<Json<JsonValue>, Json<JsonValue>>{
    let conn = connect().await?;
    let result = Entity::find()
    .select_only()
    .column_as(Column::Name, "label")
    .column_as(Column::NameEn, "name_en")
    .column_as(cust_blob("content"), "value")
    .filter(Column::Type.eq("migration"))
    .into_json().all(&conn).await;
    code::send_arr(result)
}